

#include "process.h"
#include "queue.h"
#include <stdlib.h>
#include <stdio.h>

/* By Jacob Eichers and Cliff Buchanan. Contains the functionality to implement
	the queue which helps the exponential queue and the disk*/

struct node
{
	struct process *proc;
	struct node *next;
};

/* Create a queue*/
struct qQueue *q_create()
{
	struct qQueue *myQueue;
	myQueue = malloc(sizeof(struct qQueue));
	if(!myQueue)
	{
		fprintf(stderr, "q_create: malloc failed\n");
		return NULL;
	}

	myQueue->tail = myQueue->head = NULL;

	return myQueue;
}

/* adds a value to queue. Returns 0 on success*/
int q_add(struct qQueue *line, struct process *proc)
{
	/* allocate space for a new node */
	
	struct node *data; 
	data = malloc(sizeof(struct node));
	if(!data)
	{
		fprintf(stderr, "q_add: malloc failed\n");
		return -1;
	}

	/* store the data of the process into the data*/
	data->proc = proc;

	/* if the list is empty*/
	if (q_is_empty(line))
	{
		line->head = data;
		line->tail = data;
		return 0;
	}
	/* then the list isn't empty*/
	else 
	{
		/* tail points to new data*/
		line->tail->next = data;
		/* new data becomes tail*/
		line->tail = data;

		/* return 0 to signify a successfully queued process*/
		return 0;
	}
}

/* returns top process in queue without removing.*/
struct process *q_peek(struct qQueue *line)
{
	if (!q_is_empty(line))
		{return line->head->proc;}
	else
	{
		fprintf(stderr, "q_peek: queue is empty!\n");
		return NULL;
	}
}

/* removes and returns top value of queue*/
struct process *q_remove(struct qQueue *line)
{
	struct node *oldHead;
	struct process *job;
	

	if (!q_is_empty(line))
	{
		/*store the data of the process*/
		job = line->head->proc;
		
		/* if there is only one node left*/
		if (line->head == line->tail)
		{
			free(line->head);
			line->head = NULL;
			line->tail = NULL;
			
			return job;
		}
		/* more than one node*/
		else
		{
			/* next node becomes new head node*/
			oldHead = line->head;
			line->head = line->head->next;

			/*free the old head node*/
			free(oldHead);
		}

		return job;
	}
	else
	{
		fprintf(stderr, "q_remove: queue is empty!\n");
		return NULL;
	}
}


/*returns 0 iff queue is not empty*/
int q_is_empty(struct qQueue *line)
{
	if(!line)
	{
		fprintf(stderr, "q_is_empty: line is NULL!\n");
		return -1;
	}
	
	if (!(line->head))
		{return 1;}
	else
		{return 0;}
}
